#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const ignore = require('ignore');
const program = require('commander');
const pack = require('../package.json');
const { RepoMap } = require('./repomap');

program
  .version(pack.version)
  .option(
    '-d, --directory [dir]',
    'Please specify a directory to generate repository map',
    process.cwd(),
  )
  .option('-m, --markdown', 'output markdown')
  .parse(process.argv);

let ignoreRegex = null;

const dirToJson = (path) => {
  let stats = fs.lstatSync(path),
    structure = {};

  if (stats.isDirectory()) {
    let dir = fs.readdirSync(path);

    if (ignoreRegex) {
      dir = dir.filter((val) => {
        return !ignoreRegex.test(val);
      });
    }
    dir = dir
      .filter((child) => {
        let childStats = fs.lstatSync(path + '/' + child);
        return program.onlyFolder ? childStats.isDirectory() : true;
      })
      .map((child) => {
        return dirToJson(path + '/' + child);
      });
    let dirName = path.replace(/.*\/(?!$)/g, '');
    structure[dirName] = sortDir(dir);
  } else {
    let fileName = path.replace(/.*\/(?!$)/g, '');
    return fileName;
  }
  return structure;
};

const result = dirToJson(program.directory);

let outputString = '';

function flattenJSON(data, prefix = '') {
  let result = [];

  if (Array.isArray(data)) {
    data.forEach((item, index) => {
      if (typeof item === 'object') {
        result = result.concat(flattenJSON(item, prefix));
      } else {
        result.push(`${prefix}${data[index]}`);
      }
    });
  } else if (typeof data === 'object') {
    for (let key in data) {
      if (typeof data[key] === 'object') {
        result = result.concat(flattenJSON(data[key], `${prefix}${key}/`));
      } else {
        result.push(`${prefix}${data[key]}`);
      }
    }
  }

  return result;
}

const flattenData = flattenJSON(result[Object.keys(result)[0]]);
const filterData = ignore()
  .add(fs.readFileSync(path.join(program.directory, '.gitignore')).toString())
  .add(['.venv', '.cache', '.config', '__pycache__', '*.md'])
  .filter(flattenData);

const repomap = new RepoMap(program.directory);
const output = repomap.getRankedTagsMap([], filterData);
outputString = output || '';

if (program.markdown) {
  outputString = `\`\`\`json\n${outputString}\n\`\`\``;
}

console.log(outputString);

function sortDir(arr) {
  let i = arr.length - 1;
  while (i >= 0) {
    if (typeof arr[i] === 'object') {
      let obj = arr.splice(i, 1);
      arr.push(obj[0]);
    }
    i--;
  }
  return arr;
}
